namespace RBAC.Read.Api.Application.Handler.Approval
{
    using MediatR;
    using Microsoft.Extensions.Logging;
    using RBAC.Domain.Approval;
    using RBAC.ErrorCode;
    using RBAC.Interstructrue.Base;
    using RBAC.Read.Api.Application.Command.Approval;
    using RBAC.Read.Api.Application.Dto.Approval;

    /// <summary>
    /// 获取审批流程列表处理器
    /// </summary>
    public class GetApprovalProcessListHandler : IRequestHandler<GetApprovalProcessListCommand, APIPaging<ApprovalProcessListDto>>
    {
        private readonly IBaseRepository<ApprovalProcess> approvalProcessRepository;
        private readonly IBaseRepository<ApprovalNode> approvalNodeRepository;
        private readonly IBaseRepository<ApprovalInstance> approvalInstanceRepository;
        private readonly ILogger<GetApprovalProcessListHandler> logger;

        public GetApprovalProcessListHandler(
            IBaseRepository<ApprovalProcess> approvalProcessRepository,
            IBaseRepository<ApprovalNode> approvalNodeRepository,
            IBaseRepository<ApprovalInstance> approvalInstanceRepository,
            ILogger<GetApprovalProcessListHandler> logger)
        {
            this.approvalProcessRepository = approvalProcessRepository;
            this.approvalNodeRepository = approvalNodeRepository;
            this.approvalInstanceRepository = approvalInstanceRepository;
            this.logger = logger;
        }

        /// <summary>
        /// 处理获取审批流程列表请求
        /// - 支持按流程名称、业务类型、启用状态筛选
        /// - 补充审批节点数量和进行中实例信息
        /// - 返回分页结果
        /// </summary>
        public Task<APIPaging<ApprovalProcessListDto>> Handle(GetApprovalProcessListCommand request, CancellationToken cancellationToken)
        {
            var result = new APIPaging<ApprovalProcessListDto>();
            try
            {
                cancellationToken.ThrowIfCancellationRequested();

                // 参数校验
                if (request.PageIndex <= 0) request.PageIndex = 1;
                if (request.PageSize <= 0) request.PageSize = 10;

                logger.LogInformation("开始获取审批流程列表 PageIndex={PageIndex}, PageSize={PageSize}, ProcessName={ProcessName}, ProcessType={ProcessType}, Status={Status}", 
                    request.PageIndex, request.PageSize, request.ProcessName, request.ProcessType, request.Status);

                // 构建查询条件
                var whereConditions = new List<string> { "IsDeleted = 0" };
                var parameters = new List<object>();

                if (!string.IsNullOrWhiteSpace(request.ProcessName))
                {
                    whereConditions.Add("ProcessName LIKE @ProcessName");
                    parameters.Add(new { ProcessName = $"%{request.ProcessName}%" });
                }

                if (!string.IsNullOrWhiteSpace(request.ProcessType))
                {
                    whereConditions.Add("ProcessType = @ProcessType");
                    parameters.Add(new { ProcessType = request.ProcessType });
                }

                if (request.Status.HasValue)
                {
                    whereConditions.Add("Status = @Status");
                    parameters.Add(new { Status = request.Status.Value });
                }

                var whereClause = string.Join(" AND ", whereConditions);

                // 分页查询审批流程
                var (processes, total) = approvalProcessRepository.GetPaged(
                    request.PageIndex, 
                    request.PageSize, 
                    whereClause, 
                    request.OrderBy, 
                    parameters.Count > 0 ? parameters.ToArray() : null);

                if (processes.Count == 0)
                {
                    result.Code = APIEnums.Success;
                    result.PageDatas = new List<ApprovalProcessListDto>();
                    result.TotalCount = 0;
                    result.Msg = "暂无审批流程数据";
                    return Task.FromResult(result);
                }

                // 批量查询审批节点数量
                var processIds = processes.Select(p => p.Id).ToList();
                var nodeCounts = new Dictionary<long, int>();
                var pendingInstances = new Dictionary<long, int>();

                if (processIds.Count > 0)
                {
                    try
                    {
                        var nodeCountSql = $@"
                            SELECT ProcessId, COUNT(*) as NodeCount 
                            FROM ApprovalNode 
                            WHERE IsDeleted = 0 AND ProcessId IN ({string.Join(",", processIds)})
                            GROUP BY ProcessId";
                        nodeCounts = approvalNodeRepository.Query<(long ProcessId, int NodeCount)>(nodeCountSql)
                            .ToDictionary(x => x.ProcessId, x => x.NodeCount);
                    }
                    catch (Exception ex)
                    {
                        logger.LogWarning(ex, "查询审批节点数量失败，将使用默认值0");
                    }

                    try
                    {
                        // 批量查询进行中的审批实例
                        var pendingInstanceSql = $@"
                            SELECT ProcessId, COUNT(*) as InstanceCount 
                            FROM ApprovalInstance 
                            WHERE IsDeleted = 0 AND Status IN (1, 2) AND ProcessId IN ({string.Join(",", processIds)})
                            GROUP BY ProcessId";
                        pendingInstances = approvalInstanceRepository.Query<(long ProcessId, int InstanceCount)>(pendingInstanceSql)
                            .ToDictionary(x => x.ProcessId, x => x.InstanceCount);
                    }
                    catch (Exception ex)
                    {
                        logger.LogWarning(ex, "查询进行中审批实例失败，将使用默认值");
                    }
                }

                // 映射到DTO
                var dtoList = processes.Select(p => new ApprovalProcessListDto
                {
                    Id = p.Id,
                    ProcessName = p.ProcessName,
                    Description = p.Description,
                    ProcessType = p.ProcessType,
                    BusinessType = GetBusinessTypeFromProcessType(p.ProcessType),
                    BusinessTypeName = p.ProcessType,
                    IsEnabled = p.Status == 1,
                    Status = p.Status,
                    StatusName = GetStatusName(p.Status),
                    NodeCount = nodeCounts.TryGetValue(p.Id, out var nodeCount) ? nodeCount : 0,
                    FlowDescription = GenerateFlowDescription(p.Id, nodeCounts.TryGetValue(p.Id, out var count) ? count : 0),
                    CreateTime = p.CreateTime,
                    CreateBy = p.CreateUser,
                    HasPendingInstances = pendingInstances.ContainsKey(p.Id)
                }).ToList();

                result.Code = APIEnums.Success;
                result.PageDatas = dtoList;
                result.TotalCount = total;
                result.Msg = "获取审批流程列表成功";

                logger.LogInformation("成功获取审批流程列表，共{Count}条记录", dtoList.Count);
            }
            catch (OperationCanceledException)
            {
                logger.LogWarning("获取审批流程列表被取消");
                result.Code = APIEnums.Error;
                result.Msg = "请求已取消";
                result.PageDatas = new List<ApprovalProcessListDto>();
                result.TotalCount = 0;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取审批流程列表失败: {Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "获取审批流程列表失败";
                result.PageDatas = new List<ApprovalProcessListDto>();
                result.TotalCount = 0;
            }

            return Task.FromResult(result);
        }

        /// <summary>
        /// 根据流程类型获取业务类型编号
        /// </summary>
        private static int GetBusinessTypeFromProcessType(string processType)
        {
            return processType switch
            {
                "采购订单" => 1,
                "销售订单" => 2,
                "入库单" => 3,
                "出库单" => 4,
                _ => 0
            };
        }

        /// <summary>
        /// 获取流程状态名称
        /// </summary>
        private static string GetStatusName(int status)
        {
            return status switch
            {
                1 => "正常",
                2 => "草稿",
                3 => "已停用",
                _ => "未知状态"
            };
        }

        /// <summary>
        /// 生成流程描述
        /// </summary>
        private static string GenerateFlowDescription(long processId, int nodeCount)
        {
            if (nodeCount == 0)
                return "暂无审批节点";
            
            return $"共{nodeCount}个审批节点";
        }
    }
}
